import { parse_node } from '../node_helper.js'

import { fields_helper } from '../node_helper.js'

export class BaseView {
  constructor(payload = {}) {
    const { config, action } = payload
    this._action = action
    this._config = config
  }

  get config() {
    return this._config
  }

  check_has_sheet() {
    const { arch = {} } = this.config
    const { sheet = {} } = arch
    return Object.keys(sheet).length ? true : false
  }

  get fields() {
    const in_config = this.config.fields || {}
    const in_sheet = fields_helper.fields_get_in_views({
      view_type_name: this.config
    })

    const fs = fields_helper.merge_fields(in_config, in_sheet)

    if (Object.keys(fs).length) {
      return fs
    } else {
      return this.action.config.fields || {}
    }
  }

  get action() {
    return this._action
  }

  get module() {
    return this.action.module
  }

  get env() {
    return this.action.env
  }

  get model() {
    return this.action.model
  }

  get Model() {
    return this.action.Model
  }

  get metadata() {
    return this.action.metadata
  }

  get context() {
    return this.action.context
  }

  check_metadata() {
    return this.action.check_metadata()
  }

  get_arch_for_node(node, kws) {
    const get_fields = () => {
      const fields_in_config = this.action.fields_in_config
      const models = this.action.models_in_config
      const model_name = this.model
      function format_model_name(modelname) {
        return ['model', ...modelname.split('.')].join('_')
      }
      const fields_in_model =
        (models[format_model_name(model_name)] || {}).fields || {}
      return Object.keys(fields_in_config).reduce((acc, fld) => {
        acc[fld] = {
          ...(fields_in_model[fld] || {}),
          ...(fields_in_config[fld] || {})
        }
        return acc
      }, {})
    }
    const fields = get_fields()
    const metadata = this.metadata
    const context = this.context
    const user_groups = this.action.rpc._groups.map(item => item.name)
    const kws1 = { user_groups, fields, metadata, context, env: this.env }
    const kws2 = { ...kws, ...kws1 }
    const nodes = parse_node(node, kws2)
    // console.log(node, nodes)
    return nodes
  }

  _get_buttons(info) {
    const { buttons = {} } = info
    const btns = { ...buttons }
    const btns_action = this.action.buttons
    return { ...btns_action, ...btns }
  }

  get buttons() {
    return this._get_buttons(this.config)
  }

  async unlink(rid) {
    // treeview or formview  unlink
    return this.Model.unlink(rid)
  }

  async _call_button_action({ name, record, records }) {
    const ctx_active = {
      active_id: record ? record.id : null,
      active_ids: records ? records.map(item => item.id) : [record.id],
      active_model: this.model
    }

    const context = { ...ctx_active }
    const result = {
      action_name: name,
      context,
      target: 'new',
      type: 'ir.actions.act_window'
    }

    return { result }
  }

  async _model_call_button(method, rids, kwargs = {}) {
    // const { action_map, record, records } = kwargs
    const context = this.context
    const kwargs2 = { ...kwargs, context }
    const res = await this.Model.call_button(method, rids, { ...kwargs2 })
    const { result, error } = res
    if (error) {
      if (error.code === 200) {
        if (error.data.name === 'odoo.exceptions.UserError') {
          // console.log('show error', error.data.message)
          return { error: { name: 'UserError', message: error.data.message } }
        }
      }
      console.log('call_button.error', method, error)
      return Promise.reject(error)
    } else if (result) {
      const ctx_active = {
        active_id: rids[0],
        active_ids: rids,
        active_model: this.model
      }

      const { context = {} } = result
      return { result: { ...result, context: { ...context, ...ctx_active } } }
    } else {
      return { result }
    }
  }

  async _call_button_object({ name, action_map, record, records }) {
    const ids = records ? records.map(item => item.id) : [record.id]
    const kws = { action_map, record, records }
    const res = await this._model_call_button(name, ids, { ...kws })

    const { result } = res
    if (!result) {
      return res
    }

    const { res_model } = result
    if (!res_model) {
      return res
    }

    const action_name = action_map[res_model]
    if (!action_name) {
      return res
    }

    const result2 = { action_name: action_name, ...result }

    function view_mode_get() {
      const { view_mode } = result
      if (!view_mode) {
        return
      }
      const modes = view_mode.split(',')

      // console.log(modes)
      if (modes.includes('list')) {
        return 'tree'
      }

      if (modes.includes('kanban')) {
        return 'tree'
      }

      if (modes.includes('form')) {
        return 'form'
      }
    }

    const view_type = view_mode_get()
    // console.log(view_type)

    return { result: { ...result2, view_type } }
  }

  async call_button({ type, ...kws }) {
    // const { name, action_map, record, records } = kws
    if (type === 'action') {
      return this._call_button_action({ ...kws })
    } else if (type === 'object') {
      return this._call_button_object({ ...kws })
    } else {
      const { name } = kws
      console.log('error, btn clicked', type, name)
      throw 'call_button, not type'
    }
  }
}
